﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Web;
using System.Web.Configuration;
using System.Web.SessionState;
using DotNETX.Authentication;

namespace DotNETX.Web.Handlers
{
    /// <summary>
    /// 用法
    /// <add verb="*" path="Login.ashx" type="DotNETX.Web.Handlers.LoginHandler, DotNETX.Web" />
    /// </summary>
    public class LoginHandler : BaseHandler, IRequiresSessionState
    {
        static LoginHandler()
        {
            Token_KeyName = "__token_key";

            LoginHtmlPath = WebConfigurationManager.AppSettings["DotNETX.Web.Handlers.LoginHandler.LoginHtmlPath"];
            if (!System.IO.File.Exists(HttpContext.Current.Server.MapPath(LoginHtmlPath))) LoginHtmlPath = null;
            if (LoginHtmlPath == null && System.IO.File.Exists(HttpContext.Current.Server.MapPath("~/login.html"))) LoginHtmlPath = "~/login.html";

        }
        public static IAuthenticater Authenticater { get; set; }
        public static string Token_KeyName { get; set; }
        public static string LoginHtmlPath { get; set; }

        public override void ProcessRequest(HttpContext context)
        {
            string act = Request["act"];
            string user = Request["user"];
            string pwd = Request["pwd"];
            string url = Request.QueryString["url"];

            this.SetNoCache();

            Response.ContentType = "text/json";
            if (act == null)
            {
                Response.ContentType = "text/html";
                if (string.IsNullOrEmpty(LoginHtmlPath))
                {
                    Response.Write(DotNETX.Utility.Text.HtmlUtils.CreateHtml("登录", "不好意思，登录页面离家出走了..."));
                }
                else
                {
                    Response.WriteFile(Server.MapPath(LoginHtmlPath));
                }
            }
            else if (act == "login") LoginProcess(user, pwd, url);
            else if (act == "logout") LogoutProcess();
            else if (act == "get_uid") GetUserUniqueIdProcess();
            else
            {
                Response.Write(GetJson(false, "未知请求类型!"));
            }
        }

        private void GetUserUniqueIdProcess()
        {
            try
            {
                string token = GetToken(Context);
                string uid = GetUId(token);
                Response.Write(GetJson(true, uid));
            }
            finally
            {
                Response.Write(GetJson(false, null));
            }
        }

        private void LogoutProcess()
        {
            try
            {
                string token = GetToken(Context);
                int r = Logout(token);
                Session.Remove(Token_KeyName);
                Response.Cookies.Remove(Token_KeyName);
                Response.Write(GetJson(true, null));
            }
            finally
            {
                Response.Write(GetJson(false, null));
            }
        }

        private void LoginProcess(string user, string pwd, string url=null)
        {

            if (string.IsNullOrEmpty(user))
            {
                Response.Write(GetJson(false, "请输入用户名!"));
                return;
            }
            if (string.IsNullOrEmpty(pwd))
            {
                Response.Write(GetJson(false, "请输入密码!"));
                return;
            }

            // 验证用户密码
            string token = Login(user, pwd);
            if (token == null)
            {
                Response.Write(GetJson(false, string.Format("[{0}]用户认证失败！", user)));
            }
            else
            {
                Session[Token_KeyName] = token;
                Response.Cookies.Set(new HttpCookie(Token_KeyName) { Expires = DateTime.Now.AddDays(7), Value = token });
                if(string.IsNullOrEmpty(url))
                {
                    Response.Write(GetJson(true, token));
                }
                else
                {
                    Response.Redirect(url);
                }
            }
        }

        protected virtual string Login(string user, string pwd)
        {
            if (Authenticater != null)
            {
                return Authenticater.Login(user, pwd);
            }
            return null;
        }

        protected virtual int Logout(string token)
        {
            if (Authenticater != null)
            {
                return Authenticater.Logout(token);
            }
            return 0;
        }

        protected virtual string GetUId(string token)
        {
            if (Authenticater != null)
            {
                return Authenticater.GetUId(token);
            }
            return null;
        }


        public static string GetToken(HttpContext context)
        {
            string session_token = null;
            string cookie_token = null;
            try
            {
                if (context.Session != null)
                {
                    session_token = context.Session[DotNETX.Web.Handlers.LoginHandler.Token_KeyName] as string;
                }
            }
            catch { }
            try
            {
                if (context.Request.Cookies[DotNETX.Web.Handlers.LoginHandler.Token_KeyName] != null)
                {
                    cookie_token = context.Request.Cookies[DotNETX.Web.Handlers.LoginHandler.Token_KeyName].Value;
                }
            }
            catch { }
            string token = null;
            if (session_token != null) // 优先获取session中的token
            {
                token = session_token;
            }
            else
            {
                token = cookie_token;
            }
            return token;
        }

        private string GetJson(bool s, string data)
        {
            return string.Format("{{\"success\":{0},\"data\":{1}}}", s ? "true" : "false", string.IsNullOrEmpty(data) ? "null" : "\"" + data + "\"");
        }
    }
}
